home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 331_01 / edit.c < prev    next >
Text File  |  1990-06-12  |  22KB  |  809 lines

  1.  
  2. /*
  3. HEADER:         CUG999.03;
  4. TITLE:          SE (nee E) screen editor
  5. DATE:           5/19-87;
  6.  
  7. DESCRIPTION:    "Text buffer editing routines for se"
  8. VERSION:        1.00;
  9. SYSTEM:         MS-DOS;
  10. FILENAME:       EDIT.C;
  11. SEE-ALSO:       SE.C
  12. AUTHORS:        G. Nigel Gilbert, James W. Haefner, Mel Tearle, G. Osborn;
  13. */
  14.  
  15. /*
  16.      e/qed/ged/se screen editor
  17.  
  18.     (C) G. Nigel Gilbert, MICROLOGY, 1981
  19.            August-December 1981
  20.  
  21.     FUNCTIONS: movechar, moveline, dojump, jumpline,
  22.                movepage, moveword, insertchar, replchar, deletechar,
  23.                deleteword, linedelete, crdelete, crinsert, adjustc, sync
  24.  
  25.  
  26. */
  27.  
  28. /* Earlier versions had the capabiltiy of editing text containing embedded
  29.  * tabs.  In that case the character index into text[] is less in magnitude
  30.  * than cursorx.  Due partly to the addition of new functions, charn and
  31.  * cursorx are used interchangably in this version.  This version converts
  32.  * tabs to spaces at the time the file is read.  The capability of editing
  33.  * tabs might be restored as an option in a future version, but probably a
  34.  * better way is to do an automatic entab at disc write time for those who
  35.  * want tabs.  The only advantage of embedded tabs is that they save disc
  36.  * space.  They mess up everything else.  The keyboard tab key is a cursor
  37.  * positioning command in this version.  It does not store anyting.     g.o.
  38.  */
  39.  
  40. #include <stdio.h>
  41. #include <ctype.h>
  42. #include "ged.h"
  43.  
  44. /* move cursor by 'move' columns to the right return YES unless going off text
  45.  */
  46. movechar(move)
  47. int  move;
  48. {
  49.     int  cp, len, result, j;
  50.  
  51.     cp = charn + move;
  52.     result = YES;
  53.  
  54.     if ( cp < 0 )  {
  55.         if (cline > 1) {
  56.             charn = strlen(getline(cline-1));
  57.             moveline(-1);
  58.         }
  59.     }
  60.  
  61. /* The "cursor right one char" command adds trailing spaces as needed to
  62.  * provide free cursor movement.  New characters would be lost if preceeded
  63.  * by a '\0'.
  64.  */
  65.     else if ( cp > ( len = strlen(text) ) )  {
  66.         if(!trail && move == 1) {
  67.             sync(cp);
  68.             resetcursor();
  69.             return YES;
  70.         }
  71.         else {
  72.             charn = 0;
  73.             result = moveline(1);
  74.             return result;
  75.         }
  76.     }
  77.     else {
  78.         sync(cp);  /* move +/- one on same line */
  79.         resetcursor();
  80.         return result;
  81.     }
  82. }
  83.  
  84. /* calculate line number at the top and bottom of screen.  The lines in that
  85.  * span are read from disc if not already in memory.
  86.  *
  87.  * It is convenient to be able to scroll
  88.  * by page for a few pages then page back to the original line with the
  89.  * cursor returning to its original position.  The program works
  90.  * that way for page scrolls.
  91.  */
  92.  
  93. calp()
  94. {
  95.     if (cursory < topline)
  96.         cursory = topline;
  97.     if ( (cursory - topline) > (cline - 1) )
  98.         cursory = topline + (cline - 1);    /* near bof */
  99.     pfirst = loc(cline + topline - cursory, 0);
  100.     plast = loc(pfirst + SHEIGHT - topline, 0);
  101.     if ( (cursory - topline) > (plast - pfirst) )
  102.         calp(--cursory);  /* neaar eof */
  103.     return;
  104. }
  105.  
  106. /* Move cursor by '+/- move' lines, + is downward.
  107.  * return YES if Ok, NO if going off text.
  108.  *
  109.  * Set 'cursory' to the preferred cursor y value before the call.  The
  110.  * preferred location is not always be used.  There are conditions near
  111.  * beginning and end of file when it cannot be used.  A scroll
  112.  * placing the y cursor in the preferred positiion can be forced to
  113.  * the extent possible by setting plast=-1 before the call.  The
  114.  * preferred value will otherwise not be used if a one-line
  115.  * scroll suffices, or if the new cursor position is already somewhere
  116.  * on the existing display.  The minimization of scrolling is desirable
  117.  * from a speed standpoint.  It also minimizes eye fatigue.
  118.  *
  119.  * The window movement is normally purely vertical, but there are
  120.  * exceptions.  If 'charn' has recently changed then horizontal
  121.  * display motion may result also.  If 'trail' is true then horizontal
  122.  * motion will often result due to the differing line lengths if
  123.  * the lines are long.  To cause horizontal adjstment on the new
  124.  * line, set charn before the call to moveline().  It is unnecessary
  125.  * to call sync().
  126.  *
  127.  * moveline() assumes that the existing physical display is correct and
  128.  * current.  It can't be called to show the result of an editng operation.
  129.  *
  130.  * It is assumed that the scroll function is faster than a
  131.  * rewrite, so scrolling is used when possible.  Good high-level portability
  132.  * could be achieved by writing a low-level scroll function which might
  133.  * actually do a rewrite when the hardware scroll function is missing.
  134.  * The program is being restructured so that all hardware specific
  135.  * display and terminal functions are in term.c.
  136.  */
  137.  
  138. moveline(move)
  139. int move;
  140. {
  141.     int line, i, oldoff, sav, ocline;
  142.  
  143.     puttext();
  144.  
  145.     ocline = cline;
  146.     cline = loc(cline, move);  /* read from disc if necessary */
  147.     move = cline - ocline;
  148.  
  149.     sav = curson(NO);
  150. /* gettext adds trailing spaces if needed for free cursor motion */
  151.     gettext(cline, charn);
  152.     sync(charn);
  153.  
  154.     if (plast < 0)
  155.         pfirst = -1;
  156.     if (pfirst < 0)
  157.         plast = -1;
  158.     oldoff = lastoff;
  159.     lastoff = calcoffset(charn);
  160.  
  161.     if (blocking && ( move != 1  && move != -1) )
  162.         oldoff = -1;    /* force a complete rewrite if reverse field too complex */
  163.  
  164.     if (oldoff == lastoff && cline >= pfirst && cline <= plast ) {
  165. /* the new cursor position is already on the screen */
  166.  
  167.         if (blocking)        /* the vacated line may become unmarked */
  168.             putline(ocline, cursory, NULL);
  169.  
  170.         cursory = (cline - pfirst) + topline;
  171.         calp();
  172.  
  173.         if (blocking)         /* the new line may become marked */
  174.             putline(cline, cursory, NULL);
  175.  
  176.     }
  177. /* scroll down and add one line at top */
  178. /* the old cursor can be anywhere on the screen */
  179.     else if (oldoff == lastoff && cline == pfirst -1) {
  180.         if (blocking)  /* the vacated line may become unmarked */
  181.             putline(ocline, cursory, NULL);
  182.  
  183.         scrolldown(topline);
  184.         cursory = topline;
  185.         putline(cline,topline,text);
  186.         calp();
  187.     }
  188. /* scroll up and add one line at bottom */
  189.     else if (oldoff == lastoff && cline == plast + 1) {
  190.         if (blocking)  /* the vacated line may become unmarked */
  191.             putline(ocline, cursory, NULL);
  192.  
  193.         scrollup(topline);
  194.         cursory = SHEIGHT;
  195.         putline(cline, SHEIGHT, text);
  196.         calp();
  197.     }
  198. /* Vertical screen motion of 0 or  more than 1 line, or horiz scrolling. */
  199. /* This case uses the preferred y cursor position if possible */
  200. /* moves of 0 are used to re-establish valid environment */
  201.     else  {
  202.         calp();
  203.         putpage();
  204.     }
  205.     putlineno(cline);  /* update line and column no. */
  206.     resetpcursor();
  207.     curson(sav);       /* ready to edit */
  208.     return  YES;
  209. }
  210.  
  211. dojump()
  212. {
  213.     int i;
  214.  
  215.     putmess( "[|+|/|-|]|line|, last |C|hange, |E|nd,  prior |J|ump, |M|ark;  |S|et mark");
  216.     scans(ans,2);
  217.     gotoxy(59,0);
  218.     if ( (i = calcjmp()) > 0)
  219.         jumpline(i - cline);
  220.     return;
  221. }
  222. /* calculate jump to new line.
  223.  * interpret the jump to current line (a NOP) as full screen refresh request.
  224.  * Useful for debugging and from a remote location with transmission errors
  225.  * or outages.
  226.  */
  227. calcjmp()
  228. {
  229.     int i, j, k, to;
  230.     char far *jj;
  231.     i = toupper(ans[0]);
  232.     switch (i) {
  233.  
  234.     case '+':
  235.         scans(ans,5);
  236.         to = atoi( ans );
  237.         if ( to == 0) {
  238.             cleareop(0);
  239.             putpage();
  240.         }
  241.         jmpto = cline + to;
  242.         break;
  243.  
  244.     case '-':
  245.         scans(ans,5);
  246.         if ( (to = atoi( ans ) ) )
  247.             jmpto = cline - to;
  248.         break;
  249.  
  250.     case 'C':
  251.         if (lastc < 1) {
  252.             error("No lines have been changed");
  253.             return cline;
  254.         }
  255.         cursory = topline + SHEIGHT/2;
  256.         jmpto = lastc;  /* line last changed/deleted/inserted */
  257.         break;
  258.  
  259.     case 'E':
  260.         jmpto = l